]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
shell-app: Improve discrete GPU detection
authorJan200101 <sentrycraft123@gmail.com>
Sun, 25 Jan 2026 21:33:49 +0000 (22:33 +0100)
committerMarge Bot <marge-bot@gnome.org>
Tue, 27 Jan 2026 17:55:42 +0000 (17:55 +0000)
The original logic only took into account if a GPU is the "Default",
meaning the GPU used during boot, which was intended for Laptops with
Hybrid Graphics.

The new logic uses the new Discrete key to figure out which GPU is the
most appropriate to use in order of:
- the first non-default GPU if it is discrete
- the first discrete GPU if it exists
- the first non-default GPU

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3193>

data/dbus-interfaces/net.hadess.SwitcherooControl.xml
src/shell-app.c

index e52bc1a0d25543299d94e3187c56b234680d7876..59a889654f4783ae531a58ec354cba6f586e04f9 100644 (file)
@@ -38,7 +38,8 @@
         will contain a user-facing name for the GPU, the "Environment" (as) key will
         contain an array of even number of strings, each being an environment
         variable to set to use the GPU, followed by its value, the "Default" (b) key
-        will tag the default (usually integrated) GPU.
+        will tag the default GPU, the "Discrete" (b) key tags if the GPU is a
+        dedicated component.
     -->
     <property name="GPUs" type="aa{sv}" access="read"/>
 
index 916783a5976a80c6368032bac1fdd937ec199a59..84b75beb9c362923cb7d789d9ed9d78de7cdc9b7 100644 (file)
@@ -1268,8 +1268,11 @@ apply_discrete_gpu_env (GAppLaunchContext *context,
                         ShellGlobal       *global)
 {
   GDBusProxy *proxy;
-  GVariant* variant;
+  GVariant *variant;
   guint num_children, i;
+  g_autoptr(GVariant) first_nondefault_discrete = NULL;
+  g_autoptr(GVariant) first_discrete = NULL;
+  g_autoptr(GVariant) first_nondefault = NULL;
 
   proxy = shell_global_get_switcheroo_control (global);
   if (!proxy)
@@ -1289,19 +1292,47 @@ apply_discrete_gpu_env (GAppLaunchContext *context,
   for (i = 0; i < num_children; i++)
     {
       g_autoptr(GVariant) gpu = NULL;
-      g_autoptr(GVariant) env = NULL;
       g_autoptr(GVariant) default_variant = NULL;
-      g_autofree const char **env_s = NULL;
-      guint j;
+      g_autoptr(GVariant) discrete_variant = NULL;
+      gboolean is_default = FALSE;
+      gboolean is_discrete = FALSE;
 
       gpu = g_variant_get_child_value (variant, i);
       if (!gpu ||
           !g_variant_is_of_type (gpu, G_VARIANT_TYPE ("a{s*}")))
         continue;
 
-      /* Skip over the default GPU */
-      default_variant = g_variant_lookup_value (gpu, "Default", NULL);
-      if (!default_variant || g_variant_get_boolean (default_variant))
+      default_variant = g_variant_lookup_value (gpu, "Default", G_VARIANT_TYPE_BOOLEAN);
+      if (default_variant)
+        is_default = g_variant_get_boolean (default_variant);
+
+      discrete_variant = g_variant_lookup_value (gpu, "Discrete", G_VARIANT_TYPE_BOOLEAN);
+      if (discrete_variant)
+        is_discrete = g_variant_get_boolean (discrete_variant);
+
+      if (is_discrete)
+        {
+          if (first_nondefault_discrete == NULL && !is_default)
+            first_nondefault_discrete = g_variant_ref (gpu);
+
+          if (first_discrete == NULL)
+            first_discrete = g_variant_ref (gpu);
+        }
+
+      if (first_nondefault == NULL && !is_default)
+        first_nondefault = g_variant_ref (gpu);
+    }
+
+  GVariant *gpu_list[] = { first_nondefault_discrete, first_discrete, first_nondefault };
+  
+  for (i = 0; i < G_N_ELEMENTS (gpu_list); ++i)
+    {
+      GVariant *gpu = gpu_list[i];
+      g_autoptr(GVariant) env = NULL;
+      g_autofree const char **env_s = NULL;
+      guint j;
+
+      if (!gpu)
         continue;
 
       env = g_variant_lookup_value (gpu, "Environment", NULL);